<template>
  <div>
    <Breadcrumb :opt-data="componentOptData"></Breadcrumb>
    <PageLayout>
      <div class="table-container height-100">
        <EZTable v-loading="tableLoading" :table-id="tableId" :table-hdl="tableHdl" :rows="componentList"
                 :custom-empty="true" @pageChanged="getComponentList" @sizeChanged="getComponentList"
                 @filterChange="getComponentList">
          <div slot="customOpts">
            <el-tooltip :open-delay="300" content="导入组件配置" placement="top">
              <el-upload action="" :before-upload="uploadComponentConfig"
                         class="display-inline-block mar-lft-5">
                <el-button class=" table-filter-opt-btn ">
                  <i class="iconfont icon-bendidaoru font-size-16"></i>
                </el-button>
              </el-upload>
            </el-tooltip>
          </div>
          <EmptyContent slot="empty" :opt-data="componentOptData"></EmptyContent>
        </EZTable>
      </div>
      <el-dialog v-loading="componentFormLoading" :visible.sync="showComponentDialog" :append-to-body="true" :close-on-click-modal="false"
                 :title="isEditComponent ? '修改小组件' : '新增小组件'" width="750px" top="100px">
        <el-form :ref="componentFormRef" :model="componentForm" :rules="componentFormRules" size="medium"
                 label-width="120px">
          <el-form-item prop="name" label="组件名称">
            <el-input v-model="componentForm.name" placeholder="请填写组件名称"></el-input>
          </el-form-item>
          <el-form-item prop="type" label="组件类型">
            <el-select v-model="componentForm.type" placeholder="请选择组件类型" class="width-100" @change="changeWidget">
              <el-option v-for="componentType in componentTypeArray" :key="componentType.value"
                         :label="componentType.label" :value="componentType.value"></el-option>
            </el-select>
          </el-form-item>

          <el-row :gutter="10" :span="24" v-if="componentForm.type==='compositeWidget'">
            <el-col :span="12">
              <el-form-item label="小组件行数">
                <el-input-number v-model="componentForm.widgetSize.rows" :min="1" :disabled="isEditComponent"
                                 placeholder="请填写小组件行数"></el-input-number>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="小组件列数">
                <el-input-number v-model="componentForm.widgetSize.columns" :min="1" :disabled="isEditComponent"
                                 placeholder="请填写小组件列数"></el-input-number>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="小组件功能" v-if="componentForm.type==='compositeWidget'">
            <el-select v-model="componentForm.widgetType" clearable filterable class="width-100"
                       placeholder="请选择小组件功能">
              <el-option :label="widget.label" :value="widget.value" :key="idx"
                         v-for="(widget, idx) in widgetTypeArray"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item prop="deviceType" label="设备类型"
                        v-if="componentForm.isWidget && componentForm.widgetType==='device'">
            <el-select v-model="componentForm.deviceType" clearable filterable class="width-100"
                       placeholder="请选择设备类型" @change="(val)=>getProtocolData(val)">
              <el-option :label="deviceType.name" :value="deviceType._id" :key="idx"
                         v-for="(deviceType, idx) in deviceTypeData"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="设备协议" v-if="componentForm.isWidget && componentForm.deviceType">
            <el-select v-model="componentForm.protocolId" clearable filterable class="width-100"
                       placeholder="请选择设备协议">
              <el-option :label="protocol.protocolName" :value="protocol._id" :key="idx"
                         v-for="(protocol, idx) in protocolData"></el-option>
            </el-select>
          </el-form-item>

          <el-form-item prop="version" label="版本号" v-if="isEditComponent && componentForm.status !== '未发布'">
            <el-input v-model="componentForm.version" placeholder="请填写组件版本号"></el-input>
          </el-form-item>
          <el-form-item label="主题色">
            <ThemePicker v-model="componentForm.theme"></ThemePicker>
          </el-form-item>
          <el-form-item label="预览图" v-if="isEditComponent">
            <ImageUpload :preview-type="previewType.component" :image-list="componentForm.previewImages"></ImageUpload>
          </el-form-item>
          <el-form-item prop="remarks" label="备注">
            <el-input v-model="componentForm.remarks" type="textarea" placeholder="请填写备注"></el-input>
          </el-form-item>
          <div class="mar-top text-align-right">
            <el-button type="info" @click="showComponentDialog = false">取消</el-button>
            <el-button type="primary" @click="componentFormSubmit">提交</el-button>
          </div>
        </el-form>
      </el-dialog>
      <el-dialog :visible.sync="setGroupDialog" :append-to-body="true"    :close-on-click-modal="false"
                 title="设置组件分组" width="500px" top="100px">
        <el-form :ref="groupFormRef" :model="groupForm" :rules="groupFormRules" size="medium"
                 label-width="100px">
          <el-form-item prop="group" label="设置分组：">
            <el-radio-group v-model="groupForm.group">
              <el-radio label="formal">正式组</el-radio>
              <el-radio label="test">测试组</el-radio>
            </el-radio-group>
          </el-form-item>
          <div class="mar-top text-align-right">
            <el-button type="info" @click="setGroupDialog = false">取消</el-button>
            <el-button type="primary" @click="setGroupSubmit">提交</el-button>
          </div>
        </el-form>
      </el-dialog>
    </PageLayout>
  </div>
</template>

<script>
  import {tableIdConfig, tableOptBtnConfig} from '@/config/table';
  import {deepCopy, deepCopyWithJson, downloadFileApi, editorConfigPreview, getUserInfo, JSONParse} from "@/utils";
  import {assembleTableOptBtn, getTableConfig, TableStateHdl} from "@/modules/routeParamStateHdl";
  import compositeTableCfg from "../../../config/table/compositeWidget";
  import EZTable from '../../../components/table/EZTable.vue';
  import {routerMeta} from "@/router/routerMeta";
  import {
    componentCategoryArray,
    componentGroupArray,
    componentTypeArray,
    uploadPreviewType,
    widgetTypeArray,
    userRoleCfg
  } from "@/config/common";
  import ThemePicker from "@/components/IDE/ThemePicker.vue";
  import ImageUpload from '@/components/ImageUpload.vue';
  import FileSaver from 'file-saver';
  import {assetBaseUrl} from "@/config/env";

  export default {
    name: "ComponentManagement",
    components: {
      EZTable, ThemePicker, ImageUpload
    },
    data() {
      return {
        userRoleCfg: userRoleCfg,
        userInfo: getUserInfo(),
        previewType: uploadPreviewType,
        tableId: tableIdConfig.compositeWidget,
        tableLoading: true,
        tableHdl: null,
        componentList: [],
        isEditComponent: false,
        showComponentDialog: false,
        componentFormLoading: false,
        componentFormRules: {
          name: [
            {required: true, message: '请填写组件名称', trigger: ['blur', 'change']}
          ],
          type: [
            {required: true, message: '请选择组件类型', trigger: ['blur', 'change']}
          ],
          category: [
            {required: true, message: '请选择组件功能', trigger: ['blur', 'change']}
          ],
          deviceType: [
            {required: true, message: '请选择设备类别', trigger: ['blur', 'change']}
          ],
        },
        componentForm: {},
        componentFormRef: 'componentFormRef',
        componentTypeArray: [
        {
          label: "小组件",
          value: "compositeWidget",
        }
        ],
        componentCategoryArray: componentCategoryArray,
        detailConfig: {},
        setGroupDialog: false,
        groupForm: {
          group: ''
        },
        groupFormRef: 'groupFormRef',
        groupFormRules: {
          group: [
            {required: true, message: '请选择分组', trigger: 'change'}
          ]
        },
        deviceTypeData: [],
        protocolData: [],
        widgetTypeArray: widgetTypeArray,
      }
    },
    computed: {
      componentOptData() {
        return [
          {
            type: 'btn',
            label: '公共图片管理',
            icon: 'icon-upload',
            callback: () => {
              this.$router.push({name: routerMeta.commonAsset.name});
            }
          },
          {
            type: 'btn',
            label: '新增小组件',
            icon: 'icon-tianjia',
            callback: () => {
              this.clickCreateBtn();
            }
          }
        ];
      },
      componentCategoryArrays() {
        const array = _.cloneDeep(this.deviceTypeData)
        const newObjects = [{label: '常规功能', value: 'container'}, {
          label: '小组件',
          value: 'deviceWidget'
        }, {label: '一键入会', value: 'meetingList'}];
        array.unshift(...newObjects)
        return array
      }
    },
    activated() {
      this.getDeviceTypeData()
      this.initTableConfig();
      this.initComponentForm();
      this.getComponentList();
    },
    methods: {
      initTableConfig() {
        if (this.tableHdl) return;
        const {columns = [], filters = []} = getTableConfig(this.tableId, compositeTableCfg);
        assembleTableOptBtn(columns, ({type = '', data = {}}) => {
          if (!type) return;
          const component = deepCopyWithJson(data);
          switch (type) {
            case tableOptBtnConfig.edit.type:
              this.showComponentDialog = true;
              this.isEditComponent = true;
              this.commonSetVal(component)
              this.getProtocolData(component.deviceType)
              break;
            case tableOptBtnConfig.select.type:
              window.open(this.$router.resolve({
                name: routerMeta.componentEditor.name,
                params: {cid: component._id}
              }).href, '_blank');
              break;
            case tableOptBtnConfig.copy.type:
              this.copyComponent(component);
              break;
            case tableOptBtnConfig.preview.type: {
              //预览
              editorConfigPreview({type: 'component', componentId: component._id});
              break;
            }
            case tableOptBtnConfig.delete.type:
              this.deleteComponent(component);
              break;
            case tableOptBtnConfig.audit.type:
              this.addAuditComponent(component)
              break;
            case tableOptBtnConfig.deleteAudit.type:
              this.deleteAuditComponent(component)
              break;
            case tableOptBtnConfig.export.type:
              this.exportComponentConfig(component);
              break;
            case tableOptBtnConfig.group.type:
              this.groupForm.group= component.group;
              this.setGroup(component);
              break;
            case tableOptBtnConfig.release.type:
              this.setRelease(component);
              break;
            case tableOptBtnConfig.deleteRelease.type:
              this.setDeleteRelease(component);
              break;
            case tableOptBtnConfig.exportZip.type:
              this.exportComponentZipConfig(component);
              break;
            default:
              break;
          }
        });
        this.tableHdl = new TableStateHdl(this.$route.name, this.tableId, columns, filters);
      },
      initComponentForm() {
        this.componentForm = {
          type: 'compositeWidget',
          category: 'deviceWidget',
          name: "",
          version: "",
          devices: [],
          previewImages: [],
          theme: 'theme1',
          remarks: '',
          group: '',
          widgetSize: {
            rows: 1, columns: 1
          },
          deviceType: '',
          protocolId: '',
          isWidget: true,
          widgetType: ''

        };
      },
      resetComponentForm() {
        this.initComponentForm();
        const componentForm = this.$refs[this.componentFormRef];
        componentForm && componentForm.resetFields();
      },
      getComponentList() {
        const selector = {type:'compositeWidget'};
        this.tableLoading = true;
        const tableParam = this.tableHdl.assembleTableParam();
        API.component.componentList({...tableParam, selector}).then(result => {
          this.tableLoading = false;
          const {data = [], total = 0} = result;
          this.componentList = data.map(d => {
            const componentType = componentTypeArray.find(type => type.value === d.type) || {};
            const componentCategory = this.componentCategoryArrays.find(category => category.value === d.category) || {};
            const compositeCategory = this.widgetTypeArray.find(category => category.value === d.widgetType) || {};
            const componentGroup = componentGroupArray.find(group => group.value === d.group) || {};
            const componentDeviceType = this.deviceTypeData.find(type => type._id === d.deviceType) || {};
            return {
              ...d,
              status: d.status === 0 ? '未发布' : d.status === 1 ? '审核中' : d.status === 2 ? '已发布' : d.status === 2 ? '已下架' : '--',
              //showAuditBtn: d.status === 0,
              releaseBtn: d.status === 0,
              deleteReleaseBtn: d.status === 2,
              //deleteAuditBtn: d.status === 2,
              typeText: componentType.label || '--',
              categoryText: d.type==='compositeWidget'?compositeCategory.label: componentCategory.label,
              deviceTypeText: componentDeviceType.name || '--',
              protocolTypeText: d.isGeneralWidget?'设备协议':'通用协议',
              groupText: componentGroup.label || '--',
              widgetSizes: `${d.widgetSize.rows} x ${d.widgetSize.columns}`,
              groupEditBtn: JSONParse(this.userInfo.isAdmin)
            }
          });
          this.tableHdl.total = total;
        }).catch(err => {
          console.log('err', err)
          this.tableLoading = false;
        });
      },
      clickCreateBtn() {
        this.resetComponentForm();
        this.isEditComponent = false;
        this.showComponentDialog = true;
      },
      componentFormSubmit() {
        this.$refs[this.componentFormRef].validate((valid) => {
          if (!valid) return;
          this.componentFormLoading = true;
          if (this.isEditComponent) {
            delete this.componentForm.status;
            API.component.componentEdit(this.componentForm).then((resp) => {
              this.componentFormLoading = false;
              this.showComponentDialog = false;
              this.$message({
                message: "组件编辑成功!",
                type: "success",
                duration: 1500,
              });
              this.getComponentList();
            }).catch((err) => {
              this.componentFormLoading = false;
              console.log("err: ", err);
            });
          } else {
            this.componentForm.group = "test"
            API.component.componentAdd(this.componentForm).then((resp) => {
              this.componentFormLoading = false;
              this.showComponentDialog = false;
              this.$message({
                message: "组件新增成功!",
                type: "success",
                duration: 1500,
              });
              this.getComponentList();
            }).catch((err) => {
              this.componentFormLoading = false;
              console.log("err: ", err);
            });
          }
        })
      },
      // 复制
      copyComponent(row) {
        this.$confirm(`确定要复制【${row.name}】的组件吗?`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          this.tableLoading = true;
          API.component.componentClone({_id: row._id}).then((resp) => {
            this.$message({
              message: "组件复制成功!",
              type: "success",
              duration: 1500,
            });
            this.tableLoading = false;
            this.getComponentList();
          }).catch((err) => {
            console.log("err: ", err);
            this.tableLoading = false;
          });
        }).catch(() => {
        });
      },
      //删除
      deleteComponent(row) {
        this.$confirm(`确定要删除【${row.name}】的组件吗?`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          this.tableLoading = true;
          API.component.componentDelete({componentId: row._id}).then((resp) => {
            this.$message({
              message: "组件删除成功!",
              type: "success",
              duration: 1500,
            });
            this.tableLoading = false;
            this.getComponentList();
          }).catch((err) => {
            console.log("err: ", err);
            this.tableLoading = false;
          });
        }).catch(() => {
        });
      },
      //提交审核
      addAuditComponent(row) {
        this.$confirm(`确定要提交【${row.name}】的组件吗?`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          this.tableLoading = true;
          API.component.componentReviewAdd({componentId: row._id}).then((resp) => {
            this.$message({
              message: "提交审核成功!",
              type: "success",
              duration: 1500,
            });
            this.tableLoading = false;
            this.getComponentList();
          }).catch((err) => {
            console.log("err: ", err);
            this.tableLoading = false;
          });
        }).catch(() => {
        });
      },
      deleteAuditComponent(row) {
        this.$confirm(`确定要撤回【${row.name}】的组件吗?`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          this.tableLoading = true;
          API.component.componentReviewDelete({componentId: row._id}).then((resp) => {
            this.$message({
              message: "撤回组件成功!",
              type: "success",
              duration: 1500,
            });
            this.tableLoading = false;
            this.getComponentList();
          }).catch((err) => {
            console.log("err: ", err);
            this.tableLoading = false;
          });
        }).catch(() => {
        });
      },
      //导出组件配置
      exportComponentConfig(row) {
        this.$confirm(`确定要导出【${row.name}】的组件配置吗?`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          this.tableLoading = true;
          API.component.componentExport({componentId: row._id || ''}).then(resp => {
            this.detailConfig = resp.data
            const {name = '组件'} = resp.data.component
            FileSaver.saveAs(new Blob([JSON.stringify(this.detailConfig)]), `${name}_组件配置.json`);
            this.tableLoading = false;
          }).catch(err => {
          });
        }).catch(() => {
          this.tableLoading = false;
        });
      },
      exportComponentZipConfig(row) {
        downloadFileApi(`${assetBaseUrl}/componentConfig/download/preview/assets?componentId=${row._id}`);
      },
      //导入组件配置
      uploadComponentConfig(file) {
        let fileReader = new FileReader();
        this.tableLoading = true
        fileReader.onload = async (e) => {
          try {
            const configs = JSONParse(e.target.result || "{}");
            API.component.componentImport(configs).then(() => {
              this.$message({
                message: "导入成功!",
                type: "success",
                duration: 1500,
              });
              this.getComponentList();
            }).catch((err) => {
              this.tableLoading = false
              console.log("err: ", err);
            });
          } catch (err) {
            console.log(`组件导入失败: ${err.message}`);
            this.tableLoading = false
          }
        };
        fileReader.readAsText(file);
        return false;
      },
      setGroup(row) {
        this.commonSetVal(row)
        this.setGroupDialog = true
      },
      //发布
      setRelease(row) {
        this.commonSetVal(row)
        this.componentForm.status = 2;
        API.component.componentEdit(this.componentForm).then((resp) => {
          this.componentFormLoading = false;
          this.$message({
            message: "组件发布成功!",
            type: "success",
            duration: 1500,
          });
          this.getComponentList();
        }).catch((err) => {
          console.log("err: ", err);
        });
      },
      //取消发布
      setDeleteRelease(row) {
        this.commonSetVal(row)
        this.componentForm.status = 0;
        API.component.componentEdit(this.componentForm).then((resp) => {
          this.componentFormLoading = false;
          this.$message({
            message: "组件取消发布!",
            type: "success",
            duration: 1500,
          });
          this.getComponentList();
        }).catch((err) => {
          console.log("err: ", err);
        });
      },
      setGroupSubmit() {
        this.$refs[this.groupFormRef].validate((valid) => {
          if (!valid) return;
          delete this.componentForm.status;
          this.componentForm.group = this.groupForm.group
          API.component.componentEdit(this.componentForm).then((resp) => {
            this.componentFormLoading = false;
            this.setGroupDialog = false;
            this.$message({
              message: "设置组件分组成功!",
              type: "success",
              duration: 1500,
            });
            this.getComponentList();
          }).catch((err) => {
            this.setGroupDialog = false;
            console.log("err: ", err);
          });
        })
      },
      commonSetVal(row) {
        const {
          _id,
          type,
          category,
          name,
          version,
          theme = 'theme1',
          devices = [],
          previewImages = [],
          remarks,
          group = '',
          deviceType,
          widgetSize = {rows: 1, columns: 1},
          protocolId,
          isWidget,
          widgetType
        } = row;
        this.componentForm = {
          _id, type, category, name, version, theme,
          devices, previewImages, remarks, group, deviceType, widgetSize, protocolId, isWidget, widgetType
        };
      },
      //获取所有设备
      getDeviceTypeData() {
        API.deviceType.deviceTypeAll().then(result => {
          const {data = []} = result;
          this.deviceTypeData = data;
        }).catch(err => {
          console.log('err', err)
        });
      },
      //获取关联设备协议
      getProtocolData(deviceType) {
        const param = {deviceType: deviceType};
        API.protocol.protocolAll(param).then(result => {
          const {data = []} = result;
          this.protocolData = data;
        }).catch(err => {
          console.log('err', err)
        });
      },
      changeWidget(val){
        this.componentForm.isWidget = val === 'compositeWidget';
        this.componentForm.category=val === 'compositeWidget'?'deviceWidget': 'container';
      }
    },
  }
</script>

<style scoped lang="less">
  .component-config-colors {
    width: 20px;
    height: 20px;
    float: left;
  }
</style>
